#include "electronicscalerealtimecurvepage.h"
#include "modulemanager.h"
#include "moduleelectronicscalelichen.h"
#include "moduleelectronicscaleshimadzu.h"
#include "moduleelectronicscaleconfigid.h"
#include "moduleelectronicscaleparamid.h"
#include "moduleelectronicscalecmdid.h"
#include "moduleelectronicscaledefine.h"
#include "moduleelectronicscaleeventid.h"

#include <QDateTime>
#include <QVBoxLayout>
#include <QHBoxLayout>

ElectronicScaleRealTimeCurvePage::ElectronicScaleRealTimeCurvePage(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(tr("ElectronicScale RealTime Curve Page"));
    setAttribute(Qt::WA_DeleteOnClose);

//    ModuleElectronicScaleLiChen *mod =
//            static_cast<ModuleElectronicScaleLiChen*>(moduleManager->find(ModuleID_ElectronicScale_LiChen));
    BaseModuleWithPort *mod =
            static_cast<BaseModuleWithPort*>(moduleManager->find(ModuleID_ElectronicScale_Shimadzu));
    if (mod == nullptr)
        return;

    qDebug() << mod->getName();
    connect(mod, &ModuleElectronicScaleLiChen::parseCompleted,
            this, &ElectronicScaleRealTimeCurvePage::onParseCompleted, Qt::QueuedConnection);
    connect(mod, &ModuleElectronicScaleLiChen::moduleEvent,
            this, &ElectronicScaleRealTimeCurvePage::onModuleEvent, Qt::QueuedConnection);

    {
        m_curveWeight  = new Curve(this);
        QCustomPlot &cp = m_curveWeight->getQCustomPlot();
        QSharedPointer<QCPAxisTickerDateTime> ticker(new QCPAxisTickerDateTime);
        ticker->setDateTimeFormat("hh:mm:ss");
        ticker->setDateTimeSpec(Qt::LocalTime);
        ticker->setTickCount(24);
        ticker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
        cp.xAxis->setTickLabelRotation(35);
        cp.xAxis->setTicker(ticker);
        m_curveWeight->setTitle(tr("Weight & Interval Rate Curve"));
        m_curveWeight->setXAxisName(tr("Time"));
        m_curveWeight->setYAxisName(tr("Weight(g)/Interval Rate(g/h)"));
        m_curveWeight->addGraph(tr("Weight"), QColor(Qt::red));
        m_curveWeight->addGraph(tr("Interval Rate"), QColor(Qt::green));
        m_curveWeight->show();
    }

    QHBoxLayout *hblCurve = new QHBoxLayout();
    hblCurve->addWidget(m_curveWeight);

    m_lbRecordFilePath = new QLabel(tr("Record File Path"));
    m_leRecordFilePath = new QLineEdit();
    m_pbSelectRecordFilePath = new QPushButton(tr("..."));
    connect(m_pbSelectRecordFilePath, &QPushButton::clicked, this, [=](){
        QString currentPath = m_leRecordFilePath->text();
        if (currentPath.isEmpty())
            currentPath = QDir::currentPath();
        QString path = QFileDialog::getExistingDirectory(nullptr, tr("Select directory"), currentPath, QFileDialog::ShowDirsOnly);
        if (path.isEmpty())
            path = currentPath;
        m_leRecordFilePath->setText(path);
    });

    m_lbRecordFileName = new QLabel(tr("Record File Name"));
    m_leRecordFileName = new QLineEdit();
    m_pbAutoGenerateRecordFileName = new QPushButton(tr("Auto Generate Record File Name"));
    connect(m_pbAutoGenerateRecordFileName, &QPushButton::clicked, this, [=](){
        QDateTime time = QDateTime::currentDateTime();
        QString str = time.toString("yyyy-MM-dd_hh:mm:ss");
        m_leRecordFileName->setText(str + ".xlsx");
    });
    m_pbStartRecord = new QPushButton(tr("Start"));
    connect(m_pbStartRecord, &QPushButton::clicked, this, [=](){
        QString name = m_leRecordFileName->text();
        if (name.isEmpty())
            return;

        QString path = m_leRecordFilePath->text();
        if (path.isEmpty())
        {
            path = QDir::currentPath();
            m_leRecordFilePath->setText(path);
        }
        m_recordPath = path + '/' + name;

        bool ok;
        m_period = m_lePeriod->text().toUInt(&ok);
        if (!ok)
            return;
        m_period *= 60;

        m_interval = m_leInterval->text().toUInt(&ok);
        if (!ok)
            return;

        m_curveWeight->onClear(2);

        QVariant var;
        var.setValue(m_recordPath);
        mod->setConfig(ModuleElectronicScaleConfigID_RecordFileName, var);

        var.setValue(m_period);
        mod->setConfig(ModuleElectronicScaleConfigID_RecordPeriod, var);

        var.setValue(m_interval);
        mod->setConfig(ModuleElectronicScaleConfigID_Interval, var);

        bool isSuccess = mod->setConfig(ModuleElectronicScaleConfigID_StartRecord, var);
        if (isSuccess)
        {
            m_pbStartRecord->setText(tr("Recording"));
            m_pbStartRecord->setEnabled(false);
            m_leRecordFilePath->setEnabled(false);
            m_pbSelectRecordFilePath->setEnabled(false);
            m_leRecordFileName->setEnabled(false);
            m_pbAutoGenerateRecordFileName->setEnabled(false);

            m_lePeriod->setEnabled(false);
            m_leInterval->setEnabled(false);
            m_periodCnt = 0;
            m_intervalCnt = 0;
            m_pbExport->setEnabled(false);
        }
    });
    m_pbStopRecord = new QPushButton(tr("Stop"));
    connect(m_pbStopRecord, &QPushButton::clicked, this, [=](){
        QVariant var;
        mod->setConfig(ModuleElectronicScaleConfigID_StopRecord, var);

        m_pbStartRecord->setText(tr("Start"));
        m_pbStartRecord->setEnabled(true);
        m_leRecordFilePath->setEnabled(true);
        m_pbSelectRecordFilePath->setEnabled(true);
        m_leRecordFileName->setEnabled(true);
        m_pbAutoGenerateRecordFileName->setEnabled(true);

        m_lePeriod->setEnabled(true);
        m_leInterval->setEnabled(true);
        m_pbExport->setEnabled(true);
    });

    m_lbPeriod = new QLabel(tr("Period(min)"));
    m_lePeriod = new QLineEdit();
    m_lbInterval = new QLabel(tr("Interval(s)"));
    m_leInterval = new QLineEdit();


    m_pbExport = new QPushButton(tr("Export Interval Rate"));
    connect(m_pbExport, &QPushButton::clicked, this, [=](){
        QVariant var;
        var.setValue(m_recordPath);
        mod->setConfig(ModuleElectronicScaleConfigID_ExportIntervalRateDataToXlsx, var);
    });

    QVariant var;
    mod->getConfig(ModuleElectronicScaleConfigID_RecordPeriod, var);
    m_lePeriod->setText(QString::number(var.toUInt() / 60));
    mod->getConfig(ModuleElectronicScaleConfigID_Interval, var);
    m_leInterval->setText(QString::number(var.toUInt()));


    QHBoxLayout *hblRecord = new QHBoxLayout();
    hblRecord->addWidget(m_lbRecordFilePath);
    hblRecord->addWidget(m_leRecordFilePath);
    hblRecord->addWidget(m_pbSelectRecordFilePath);
    hblRecord->addWidget(m_lbRecordFileName);
    hblRecord->addWidget(m_leRecordFileName);
    hblRecord->addWidget(m_pbAutoGenerateRecordFileName);
    QHBoxLayout *hblAction = new QHBoxLayout();
    hblAction->addWidget(m_lbPeriod);
    hblAction->addWidget(m_lePeriod);
    hblAction->addWidget(m_lbInterval);
    hblAction->addWidget(m_leInterval);
    hblAction->addWidget(m_pbStartRecord);
    hblAction->addWidget(m_pbStopRecord);
    hblAction->addWidget(m_pbExport);

    QVBoxLayout *vbl = new QVBoxLayout();
    vbl->addLayout(hblCurve);
    vbl->addLayout(hblRecord);
    vbl->addLayout(hblAction);
    setLayout(vbl);
}

ElectronicScaleRealTimeCurvePage::~ElectronicScaleRealTimeCurvePage()
{

}

void ElectronicScaleRealTimeCurvePage::closeEvent(QCloseEvent *event)
{
    disconnect();
    event->accept();
}

void ElectronicScaleRealTimeCurvePage::onParseCompleted(int id, const QVariant &var)
{
    switch (id)
    {
        case electronicscale::ElectronicScaleCmdID_Weight:
        {
            electronicscale::Sample sample = var.value<electronicscale::Sample>();
            QDateTime t = QDateTime::fromMSecsSinceEpoch(sample.time);
            double time = QCPAxisTickerDateTime::dateTimeToKey(t);
            m_curveWeight->onAddGraphPoint(0, time, sample.weight.value);
        }
        break;
        default:
        break;
    }
}

void ElectronicScaleRealTimeCurvePage::onModuleEvent(int id, const QVariant &var)
{
    switch (id)
    {
        case ModuleElectronicScaleEventID_ShowIntervalRate:
        {
            electronicscale::IntervalRate rate = var.value<electronicscale::IntervalRate>();
            QDateTime t = QDateTime::fromMSecsSinceEpoch(rate.time);
            double time = QCPAxisTickerDateTime::dateTimeToKey(t);
            m_curveWeight->onAddGraphPoint(1, time, rate.rate.value);
        }
        break;
        default:
        break;
    }
}
